using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MFramework;
using UnityEngine.EventSystems;
using UnityEngine.SceneManagement;
using System;
using UnityEngine.UI;
using TMPro;

public class UIGame : MonoBehaviour
{
    public int row;
    public int col;
    public float intervalX = 100;
    public float intervalY = 100;

    public float maxTime = 60;

    [HideInInspector]
    public int score = 0;
    [HideInInspector]
    public float leftTime = 60;
    [HideInInspector]
    public bool isPlaying = false;

    private GameObject m_cardPanel;
    private AssetHandle m_cardHandle;

    private Card[,] m_cards;
    private List<Card> m_selectedCardList;

    private UIEventListener m_btnDeleteListener;
    private UIEventListener m_btnRestartListener;
    private TMP_Text m_txtScore;
    private TMP_Text m_txtTime;

    private void Awake()
    {
        m_cardPanel = transform.FindChildByName("CardPanel").gameObject;
        m_cards = new Card[row, col];
        m_selectedCardList = new List<Card>();

        m_txtScore = transform.FindChildByName("TxtScore").GetComponent<TMP_Text>();
        m_txtTime = transform.FindChildByName("TxtTime").GetComponent<TMP_Text>();
        m_btnDeleteListener = transform.FindChildByName("BtnDelete").GetComponent<UIEventListener>();
        m_btnRestartListener = transform.FindChildByName("BtnRestart").GetComponent<UIEventListener>();
        m_btnDeleteListener.PointerClick += OnBtnDeleteClick;
        m_btnRestartListener.PointerClick += OnBtnRestartClick;
    }

    private void Start()
    {
        m_cardHandle = ResourcesManager.LoadAsset<GameObject>("Assets/GameRes/Prefabs/Card");

        InitGame();
    }

    private void InitGame()
    {
        score = 0;
        m_txtScore.text = "Scroe: 0";
        for (int i = 0; i < row; ++i)
        {
            for (int j = 0; j < col; ++j)
            {
                GenerateCard(i, j);
            }
        }
        m_selectedCardList.Clear();
        isPlaying = true;
        StopAllCoroutines();
        StartCoroutine(CountDownTime());
    }

    public void TrySelectCard(Card card)
    {
        if (!isPlaying) return;

        if (m_selectedCardList.Contains(card))
        {
            m_selectedCardList.Remove(card);
            card.OnUnSelect();
        }
        else if(m_selectedCardList.Count < 3)
        {
            m_selectedCardList.Add(card);
            card.OnSelect();
        }

        if(m_selectedCardList.Count == 3)
        {
            if(m_selectedCardList[0].CompleteNotSame(m_selectedCardList[1]) 
                && m_selectedCardList[0].CompleteNotSame(m_selectedCardList[2])
                && m_selectedCardList[1].CompleteNotSame(m_selectedCardList[2]))
            {
                score += 3;
                m_txtScore.text = "Score: " + score;

                foreach (Card c in m_selectedCardList)
                {
                    GenerateCard(c.row, c.col);
                }

                m_selectedCardList.Clear();
            }
        }
    }

    private IEnumerator CountDownTime()
    {
        leftTime = maxTime;
        m_txtTime.text = "Time: " + leftTime;

        while (leftTime > 0)
        {
            yield return new WaitForSeconds(1f);
            leftTime -= 1;
            m_txtTime.text = "Time: " + leftTime;

            if(leftTime == 0)
            {
                isPlaying = false;
            }
        }
    }

    private void GenerateCard(int i, int j)
    {
        if(m_cards[i, j])
        {
            Destroy(m_cards[i, j].gameObject);
        }
        GameObject cardGO = m_cardHandle.InstantiateSync(m_cardPanel.transform);
        (cardGO.transform as RectTransform).anchoredPosition = new Vector2(intervalX * (j - (col - 1.0f) / 2), intervalY * ((row - 1.0f) / 2 - i));
        m_cards[i, j] = cardGO.GetComponent<Card>();
        m_cards[i, j].row = i;
        m_cards[i, j].col = j;
    }

    private void OnBtnDeleteClick(PointerEventData eventData)
    {
        if (!isPlaying) return;

        foreach(Card card in m_selectedCardList)
        {
            GenerateCard(card.row, card.col);
        }
        m_selectedCardList.Clear();
    }

    private void OnBtnRestartClick(PointerEventData eventData)
    {
        InitGame();
    }

    private void OnDestroy()
    {
        if (m_cardHandle != null)
        {
            m_cardHandle.Release();
            m_cardHandle = null;
        }
    }
}
